(function ($) {
	var me = {};
	window.FormElement = Class.create({
		// 继承的父类
		Extends: Basis,
		// 混入的集合
		//Mixes: EventMixin,
		// 静态方法
		//Statics: {},
		// 构造
		constructor: function(element, options){
			this.element = $(element);
			me = this;
			// 清空数据
			me.set('elementOption',[]);
			me.set('editData',{});
			// 清空数据
			$.each(options,function(k,v){
				if( v == undefined && v == null ) return true;
				if( typeof v === 'object' ) {
					$.extend(me.get(k),v);
				} else {
					me.set(k,v);
				}
			});
			// 设置配置
			me.set('formId',this.element.attr('id'));
		},
		// 表单ID
		formId: "",
		// 编辑页数据
		editData: {},
		// 表单元素验证规则
		validateRules: {},
		// 表单元素验证提示
		validateMessages: {},
		// 表单配置
		elementOption: [],
		// 表单元素模板
		elementTpl: '<div class="form-group">' +
				'<label class="col-sm-3 control-label no-padding-right" for="form-field-2">{2}{0}：</label>' +
				'<div class="col-sm-9">' +
					'{1}' +
				'</div>' +
			'</div>' +
			'<div class="space-4"></div>',
		// 标记模板
		markTpl: '<span class="red">*</span>',
		// 提示模板
		tipsTpl: ' data-rel="tooltip" data-placement="bottom" ',
		// input模板
		inputTpl: '<div class="clearfix">' +
					'<input type="{0}" name="{2}" class="{3} {1}" value="{4}" placeholder="{5}" {6} {7} {10} {11} data-original-title="{12}" />' +
				'</div>',
		// input组装
		inputBuild: function(option){},
		// input渲染
		inputRender: function( option ){},
		// date模板
		datetimeTpl: '<div class="input-group">' +
					'<input type="text" name="{2}" class="{3} {1}" value="{4}" data-placeholder="{5}" {6} {7} data-date-format="{8}" {10} {11} data-original-title="{12}" />' +
					//'<span class="input-group-addon">' +
					//	'<i class="fa fa-calendar bigger-110"></i>' +
					//'</span>' +
				'</div>',
		// datetime组装
		datetimeBuild: function(option){},
		// datetime渲染
		datetimeRender: function( option ){
			$('.' + option.id).datetimepicker({
				//format: 'YYYY/MM/DD HH:mm:ss',//use this option to display seconds
				icons: {
					time: 'fa fa-clock-o',
					date: 'fa fa-calendar',
					up: 'fa fa-chevron-up',
					down: 'fa fa-chevron-down',
					previous: 'fa fa-chevron-left',
					next: 'fa fa-chevron-right',
					today: 'fa fa-arrows ',
					clear: 'fa fa-trash',
					close: 'fa fa-times'
				}
			}).next().on(ace.click_event, function(){
				$(this).prev().focus();
			});
		},
		// select模板
		selectTpl: '<select name="{2}" class="{3} {1}" data-placeholder="{5}" {9} >' +
					'{4}' +
				'</select>',
		// select组装
		selectBuild: function(option){
			var list = {}, html = option.multiple ? '' : '<option value="">' + ( option.placeholder != '' ? option.placeholder : "" ) + '</option>';
			if( typeof(option.data) == "object" ) {
				$.each(option.data,function(key,val){
					if( typeof(val) == "object" ) {
						list[val[option.fieldKey]] = val[option.fieldValue];
					} else if( typeof(val) == "string" ) {
						list[key] = val;
					}
				});
			} else if( typeof(option.data) == "string" ) {
				$.ajax({
					type: "get",
					dataType: "json",
					url: me.getUrl(option.data),
					data: option.dataParam || {},
					async: false,
					success: function(data){
						var dataList = option.dataSrc != '' ? data.result : data ;
						$.each(dataList,function(key,val){
							if( typeof(val) == "object" ) {
								list[val[option.fieldKey]] = val[option.fieldValue];
							} else if( typeof(val) == "string" ) {
								list[key] = val;
							}
						});
					},
					error: function(data){}
				});
				
			}
			$.each(list,function(key,val){
				html += '<option ' + ( option.value == key ? "selected" : "" ) + ' value="' + key + '">' + val + '</option>';
			});
			return html;
		},
		// select渲染
		selectRender: function( option ){
			if( me.formId.indexOf("Search") != -1 ) return;
			if( ace.vars['touch']) return;
			$('.' + option.id).chosen({allow_single_deselect:true});
		},
		// text模板
		textareaTpl: '<div class="clearfix">' +
						'<textarea name="{2}" class="{3} {1}" placeholder="{5}" {6} {7} {10} {11} data-original-title="{12}" >{4}</textarea>' +
					'</div>',
		// textarea组装
		textareaBuild: function(option){},
		// textarea渲染
		textareaRender: function( option ){},
		// file参数
		fileOption: {
			style : 'well',
			no_file: '',
			btn_choose: '将文件拖放到此处或单击以选择',
			btn_change: null,
			no_icon: 'ace-icon fa fa-cloud-upload',
			icon_remove: null,
			roppable: false,
			droppable: true,
			thumbnail: 'small',//false | large | fit
			maxSize: 220000,//bytes
			allowExt: [],//["jpeg", "jpg", "png", "gif"],
			denyExt:[],
			allowMime: [],//["image/jpg", "image/jpeg", "image/png", "image/gif"],
			denyMime:[],
			onchange: null,
			before_change: null,
			before_remove: null,
		},
		// file模板
		fileTpl: '<input type="file" name="{2}" class="{3} {1}" value="{4}" placeholder="{5}" {6} {7} {9} {10} {11} data-original-title="{12} />',
		// file组装
		fileBuild: function(option){},
		// file渲染
		fileRender: function( option ){
			$.extend(me.fileOption,option.fileOption);
			$('.' + option.id).ace_file_input(me.fileOption);
		},
		// editor数据
		editorObj: {},
		// editor参数
		editorOption: {
			cssPath : '',
			allowFileManager : true,
			afterBlur : function(){
				this.sync();
			}
		},
		// editor模板
		editorTpl: '<div class="clearfix">' +
						'<textarea name="{2}" class="{3} {1}" >{4}</textarea>' +
					'</div>',
		// editor组装
		editorBuild: function(option){
		},
		// editor渲染
		editorRender: function( option ){
			$.extend(me.editorOption,option.editorOption);
			me.editorObj[option.id] = KindEditor.create('textarea[name="' + option.id + '"]', me.editorOption);
		},
		// treeview参数
		treeviewOption: {
			'dataSource': function(options, callback){},
			'multiSelect': false,
			'cacheItems' : true,
			'open-icon' : 'ace-icon tree-minus',
			'close-icon' : 'ace-icon tree-plus',
			'itemSelect' : true,
			'folderSelect': false,
			'selected-icon' : 'ace-icon fa fa-check',
			'unselected-icon' : 'ace-icon fa fa-times',
			'loadingHTML' : '<div class="tree-loading"><i class="ace-icon fa fa-refresh fa-spin blue"></i></div>'
		},
		// treeview模板
		treeviewTpl:'<div class="widget-main padding-8 tree-container">' +
						'<ul class="{1}"></ul>' +
					'</div>',
		// treeview组装
		treeviewBuild: function( option ){
			var dataList = option.data;
			var fieldKey = option.fieldKey || 'id';
			var fieldValue = option.fieldValue || 'name';
			if( typeof(option.data) == "string" ) {
				$.ajax({
					type: "get",
					dataType: "json",
					url: me.getUrl(option.data),
					data: option.dataParam || {},
					async: false,
					success: function(data){
						dataList = option.dataSrc != '' ? data.result : data ;
					},
					error: function(data){}
				});
			}
			var dataSource1 = function(options, callback){
				var $data = {};
				if( JSON.stringify(options) == "{}" ) {
					//the root tree
					$data = dataList;
				} else if( JSON.stringify(options.children) != "{}" ) {
					$data = options.children;
				}
				if( typeof($data) == "object" ) {
					var valueArr = option.value ? option.value.split(',') : [];
					$.each($data,function(k,v){
						$data[k]['text'] = v[fieldValue];
						$data[k]['type'] = typeof(v.children) != "undefined" ? 'folder' : 'item';
						//选中判断
						if( $.inArray(v[fieldKey], valueArr) != -1 ) {
							$data[k]["additionalParameters"] = {'item-selected': true};
						}
					});
				}
				return callback({ data: $data });
				//this setTimeout is only for mimicking some random delay
				/*if($data != null) {
					setTimeout(function(){callback({ data: $data });} , parseInt(Math.random() * 500) + 200);
				}*/
			}
			return dataSource1;
		},
		// treeview渲染
		treeviewRender: function( option ){
			var multiple = option.multiple || false;
			$.extend(me.treeviewOption,option.treeviewOption);
			me.treeviewOption.dataSource = me.treeviewBuild(option),
			me.treeviewOption.multiSelect = multiple,
			$('.'+option.id).ace_tree(me.treeviewOption);
			$('.tree-container').ace_scroll({size: 250, mouseWheelLock: true});
			$('.'+option.id).on('closed.fu.tree disclosedFolder.fu.tree', function() {
				$('.tree-container').ace_scroll('reset').ace_scroll('start');
			});
		},
		// moveselect模板
		moveselectTpl:'<select id= "duallist" name="{2}" class="{3} {1}" data-placeholder="{5}" {9} >' +
					'{4}' +
				'</select>',
		// moveselect渲染
		moveselectRender: function( option ){
			var demo1 = $('select[name="'+option.field+'"]').bootstrapDualListbox({infoTextFiltered: '<span class="label label-purple label-lg">Filtered</span>'});
			var container1 = demo1.bootstrapDualListbox('getContainer');
			container1.find('.btn').addClass('btn-white btn-info btn-bold');
		
			/**var setRatingColors = function() {
				$(this).find('.star-on-png,.star-half-png').addClass('orange2').removeClass('grey');
				$(this).find('.star-off-png').removeClass('orange2').addClass('grey');
			}*/
			$('.rating').raty({
				'cancel' : true,
				'half': true,
				'starType' : 'i'
				/**,
				
				'click': function() {
					setRatingColors.call(this);
				},
				'mouseover': function() {
					setRatingColors.call(this);
				},
				'mouseout': function() {
					setRatingColors.call(this);
				}*/
			})//.find('i:not(.star-raty)').addClass('grey');
			
			
			
			//////////////////
			//select2
			$('.select2').css('width','200px').select2({allowClear:true})
			$('#select2-multiple-style .btn').on('click', function(e){
				var target = $(this).find('input[type=radio]');
				var which = parseInt(target.val());
				if(which == 2) $('.select2').addClass('tag-input-style');
				 else $('.select2').removeClass('tag-input-style');
			});
			
			//////////////////
			$('.multiselect').multiselect({
			 enableFiltering: true,
			 enableHTML: true,
			 buttonClass: 'btn btn-white btn-primary',
			 templates: {
				button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"><span class="multiselect-selected-text"></span> &nbsp;<b class="fa fa-caret-down"></b></button>',
				ul: '<ul class="multiselect-container dropdown-menu"></ul>',
				filter: '<li class="multiselect-item filter"><div class="input-group"><span class="input-group-addon"><i class="fa fa-search"></i></span><input class="form-control multiselect-search" type="text"></div></li>',
				filterClearBtn: '<span class="input-group-btn"><button class="btn btn-default btn-white btn-grey multiselect-clear-filter" type="button"><i class="fa fa-times-circle red2"></i></button></span>',
				li: '<li><a tabindex="0"><label></label></a></li>',
		        divider: '<li class="multiselect-item divider"></li>',
		        liGroup: '<li class="multiselect-item multiselect-group"><label></label></li>'
			 }
			});
		},
		// 创建表单元素
		// {id:'id',title:'序号',type:"text"},
		// {id:'id',title:'序号',field:'id',type:"text",className:"input-small",value:'',placeholder:"序号",disabled:false,readonly:false},
		// {id:'datePicker',title:'时间',type:"date",format:"yyyy-mm-dd"},
		createElement: function(){
			$.each(me.elementOption,function(k,v){
				if( $.isEmptyObject(v) ) return true;
				var $form = me.element, inputType = '', html = '', render = function(){}, rules = v.rules || {}, messages = v.messages || {};
				var title = v.title || '', type = v.type || 'text', id = v.id || 'id', name = v.field || id, placeholder = v.placeholder || title, tooltip = v.tooltip || '', editType = v.editType || "";
				var className = v.className || ( type == 'datetime' || $form.attr('role') != 'form' ? 'form-control' : 'col-xs-10 col-sm-5');
				v.value = me.editData[name] || v.value;
				if(  typeof(rules) !== 'object' ) {
					rules = JSON.parse(rules);
				}
				if(  typeof(messages) !== 'object' ) {
					messages = JSON.parse(messages);
				}
				var value = v.value || '', disabled = v.disabled ? "disabled" : "", readonly = v.readonly ? "readonly" : "", format = v.format || '', multiple = v.multiple ? "multiple" : "";
				var required = rules.required != undefined && rules.required ? "required" : "", requiredMark = required ? me.markTpl : "";
				// 修改页情况下
				editDataKey = Object.keys(me.editData);
				if( editDataKey != 0 && editType == 'hidden' ) {
					v.type = type = 'hidden';
					rules = messages = '';
				} else if( editDataKey != 0 && editType == 'disabled' ) {
					disabled = 'disabled'
				}
				// 表单元素类型
				if( v.type == 'datetime' ) {
					inputType = 'datetime';
					format = format || 'YYYY-MM-DD HH:mm:ss';
				} else if( v.type == 'select' ) {
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请选择...";
					value = me.selectBuild(v);
				} else if( v.type == 'textarea' ) {
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请输入...";
				} else if( v.type == 'file' ) {
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请选择...";
				} else if( v.type == 'editor' ){
					inputType = v.type;
				} else if( v.type == 'treeview' ){
					inputType = v.type;
				} else if( v.type == 'moveselect' ){
					inputType = v.type;
					value = me.selectBuild(v);
				}else {
					inputType = 'input';
				}
				html = me[inputType + 'Tpl'].format(type,id,name,className,value,placeholder,disabled,readonly,format,multiple,required,me.tipsTpl,tooltip);
				if( v.type != 'hidden' ) {
					html = me.elementTpl.format(title,html,requiredMark);
				}
				$form.append(html);
				// 渲染
				render = me[inputType + 'Render'] || render;
				render(v);
				// 设置验证规则
				if( rules != '' ) {
					me.validateRules[v.id] = rules;
				}
				if( messages != '' ) {
					me.validateMessages[v.id] = messages;
				}
			});
		},
		// 创建Element
		load: function(){
			me.beforeLoad();
			me.createElement();
			me.afterLoad();
		},
		// 加载数据前操作
		beforeLoad: function(){},
		// 加载数据之后操作
		afterLoad: function(){
			// 设置样式
			$('[data-rel=tooltip]').tooltip({container:'body'});
			$('[data-rel=popover]').popover({container:'body'});
		},
	});
    /**
     * 扩展 Jquery 对象为 FormElement
     * @param option
     */
    $.fn.formElement = function(option){
        return this.each(function () {
            var $this = $(this),
                data = $this.data('formElement'),
                options = typeof option === 'object' && option;
            if (!data)  {
                $this.data('formElement', (data = new FormElement(this, $.extend({}, options))));
            }
            if (typeof option == 'string') {
                data[option]();
            }
            if(data.autoLoad){
                data.load();
            }
        });
    };
    /**
     * 属性返回对创建此对象的函数的引用
     */
    $.fn.formElement.Constructor = FormElement;

})(jQuery);

